#pragma once

#include <boostext/util/make_shared.hpp>

#include "exports.hpp"
#include "Message.hpp"
#include "Callstack.hpp"




namespace Engine
{
	namespace Debugger
	{
		/**
		 * A Response can be seen as the response / return value to a Command.
		 *
		 * It carries the uuid of the Command it has been sent as a response to, so
		 * that it can always be matched to a Command.
		 */
		class ENGINE_DEBUGGER_API Response
			: public Message
		{
		public:

			SHARED(Response);

			Response();
			Response(boost::uuids::uuid tag);



			/**
			 * @returns the type of this Notification
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API ScriptStateResponse
			: public Response
		{
		public:

			ScriptStateResponse();

			/**
			 * Creates a ScriptState response that indicates a success.
			 */
			ScriptStateResponse(const std::vector<char>& state, boost::uuids::uuid tag);

			/**
			 * Creates a ScriptState response that indicates failure.
			 */
			ScriptStateResponse(boost::uuids::uuid tag);



			/**
			 * @returns the type of this application
			 */
			virtual Type type() const;

			/**
			 * @returns the script state
			 */
			const std::vector<char>& value() const;

			/**
			 * Stores this notification in the given stream.
			 */
			virtual void store(boostext::iostreams::bin_ostream& stream) const;

			/**
			 * Restores this notification from the given stream.
			 */
			virtual void restore(boostext::iostreams::bin_istream& stream);

		private:

			/// The actual data... the script engine's state
			std::vector<char>   m_state;

			/// Weather or not the command failed
			bool                m_failed;
		};
		///////////////////////////////////////////////////////////////////////////////////////////

		class ENGINE_DEBUGGER_API CallstackResponse
			: public Response
		{
		public:

			CallstackResponse();

			/**
			 * Creates a Callstack response that indicates a success.
			 */
			CallstackResponse(const Debugger::Callstack& callstack, boost::uuids::uuid tag);

			/**
			 * Creates a Callstack response that indicates failure.
			 */
			CallstackResponse(boost::uuids::uuid tag);



			/**
			 * @returns the type of this application
			 */
			virtual Type type() const;

			/**
			 * @returns the callstack
			 */
			const Debugger::Callstack& value() const;

			/**
			 * Stores this notification in the given stream.
			 */
			virtual void store(boostext::iostreams::bin_ostream& stream) const;

			/**
			 * Restores this notification from the given stream.
			 */
			virtual void restore(boostext::iostreams::bin_istream& stream);

		private:

			/// The actual data... the callstack
			Debugger::Callstack   m_stack;

			/// Weather or not the command failed
			bool                  m_failed;
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
